package com.danbay.cloud.deviceaccess.service;

import com.danbay.cloud.device.api.dto.DeviceLoginDto;
import com.danbay.cloud.device.api.dto.DeviceRegDto;
import com.danbay.cloud.deviceaccess.api.dto.DeviceLogin;
import com.danbay.cloud.deviceaccess.api.dto.DeviceLogout;
import com.danbay.cloud.deviceaccess.api.dto.DeviceReg;
import com.danbay.cloud.deviceaccess.api.dto.DeviceRegResult;
import com.danbay.cloud.deviceaccess.api.service.IDeviceManageService;
import com.danbay.cloud.deviceaccess.client.DeviceLoginServiceClient;
import com.danbay.cloud.deviceaccess.client.DeviceRegServiceClient;
import com.danbay.framework.exception.BusinessException;
import com.danbay.framework.kafka.KafkaContext;
import com.danbay.framework.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 设备管理服务（注册、登录、登出）
 *
 * @author SJG
 *         2017/9/28
 */
@Service
@Slf4j
public class DeviceManageService implements IDeviceManageService {

    private final DeviceCacheService deviceCacheService;

    private final DeviceLoginServiceClient deviceLoginServiceClient;

    private final DeviceRegServiceClient deviceRegServiceClient;


    @Autowired
    public DeviceManageService(DeviceCacheService deviceCacheService, DeviceLoginServiceClient deviceLoginServiceClient, DeviceRegServiceClient deviceRegServiceClient) {
        this.deviceCacheService = deviceCacheService;
        this.deviceLoginServiceClient = deviceLoginServiceClient;
        this.deviceRegServiceClient = deviceRegServiceClient;
    }

    /**
     * 注册设备
     * @param deviceReg 注册设备信息
     * @throws BusinessException 业务异常
     */
    @Override
    public DeviceRegResult register(DeviceReg deviceReg) throws BusinessException {
        String deviceId = deviceCacheService.getRegisteredDevId(deviceReg.getMac());
        if (StringUtils.isNotBlank(deviceId)) {
            String oldDeviceCtrlId = deviceCacheService.getDeviceCtrlId(deviceId);
            if (oldDeviceCtrlId == null) {
                log.info("设备已存在，mac:{},devId:{}，无需再注册",deviceReg.getMac(),deviceId);
                return DeviceRegResult.builder().id(deviceId).build();
            }
            //如果上传的中控设备id与原有的中控设备id不一致，则表示设备发生了迁移，需要提交device-service处理
            if (deviceReg.getFatherDevId() != null && !deviceReg.getFatherDevId().equals(oldDeviceCtrlId)) {
                log.info("设备:{}已存在，但迁移到了中控:{}",deviceReg.getMac(),deviceReg.getFatherDevId());
            }
        }
        //检查中控是否已注册
        if (StringUtils.isNotEmpty(deviceReg.getFatherDevId())) {
            //如果设备数据先过来，中控后到，则会造成本次不能完成设备注册，需要等设备下次推送数据过来
            if (!deviceCacheService.devIdIsRegistered(deviceReg.getFatherDevId())) {
                log.warn("该设备关联了父级设备,但该父级设备信息还未注册!" +
                        ",sn:{},mac:{},fatherDevId:{}",deviceReg.getSn(),deviceReg.getMac(),deviceReg.getFatherDevId());
                throw new BusinessException("该设备关联的父级设备还未注册!");
            }
        }
        //未注册的设备，需要提交到云端注册
        deviceId = deviceRegServiceClient.register(
                DeviceRegDto.builder().
                        sn(deviceReg.getSn()).
                        mac(deviceReg.getMac()).
                        ver(deviceReg.getVer()).
                        ip(deviceReg.getIp()).
                        fatherDevId(deviceReg.getFatherDevId()).
                        build()
        );

        log.info("设备提交云端注册成功!devId:{},name:{},mac:{},ip:{}",
                deviceId, deviceReg.getSn(), deviceReg.getMac(), deviceReg.getIp());
        //根据deviceId缓存注册数据
        deviceCacheService.setRegMsg(deviceId,deviceReg);
        return DeviceRegResult.builder().id(deviceId).build();
    }


    /**
     * 设备登录:
     *
     * @param deviceLogin 设备登录信息
     */
    @Override
    public void login(DeviceLogin deviceLogin) throws BusinessException {
        if (!deviceCacheService.devIdIsRegistered(deviceLogin.getDevId())) {
            throw new BusinessException("设备:" + deviceLogin.getDevId() + "还未注册!");
        }
        deviceLoginServiceClient.login(new DeviceLoginDto(deviceLogin.getDevId(), deviceLogin.getOwner(), deviceLogin.getIp(),deviceLogin.getVersion()));
        //映射设备id与topic的关系
        KafkaContext.mapTopic(deviceLogin.getDevId());
        deviceCacheService.cacheDeviceTopic(deviceLogin.getDevId(),KafkaContext.getTopic());
        log.info("设备提交云端登录成功!devId:{}", deviceLogin.getDevId());
    }

    /**
     * 设备登出
     *
     * @param deviceLogout 设备登出信息
     */
    @Override
    public void logout(DeviceLogout deviceLogout) throws BusinessException {
        deviceLoginServiceClient.logout(new DeviceLoginDto(deviceLogout.getDevId(), "", "",""));
        log.info("设备提交云端登出成功!devId:{}", deviceLogout.getDevId());
    }


}
